use std::sync::Arc;
use std::collections::HashMap;
use std::fmt::{Debug, Display};
use std::time::{Duration, Instant};
use std::sync::atomic::{AtomicU64, Ordering};
use dashmap::DashMap;
use parking_lot::RwLock;

/// 指标系统
pub trait Metrics: Send + Sync + 'static {
    /// 创建计数器
    fn create_counter(&self, name: &str, description: &str, labels: &[&str]) -> Box<dyn Counter>;
    
    /// 创建仪表盘
    fn create_gauge(&self, name: &str, description: &str, labels: &[&str]) -> Box<dyn Gauge>;
    
    /// 创建直方图
    fn create_histogram(&self, name: &str, description: &str, labels: &[&str], buckets: &[f64]) -> Box<dyn Histogram>;
}

/// 计数器接口
pub trait Counter: Send + Sync + 'static {
    /// 增加计数器值
    fn inc(&self);
    
    /// 增加计数器值（带有标签）
    fn inc_with_labels(&self, label_values: &[&str]);
    
    /// 增加计数器值（指定数量）
    fn add(&self, value: f64);
    
    /// 增加计数器值（指定数量，带有标签）
    fn add_with_labels(&self, value: f64, label_values: &[&str]);
    
    /// 获取计数器当前值
    fn value(&self) -> f64;
    
    /// 获取带标签的计数器当前值
    fn value_with_labels(&self, label_values: &[&str]) -> f64;
}

/// 仪表盘接口
pub trait Gauge: Send + Sync + 'static {
    /// 设置仪表盘值
    fn set(&self, value: f64);
    
    /// 设置仪表盘值（带有标签）
    fn set_with_labels(&self, value: f64, label_values: &[&str]);
    
    /// 增加仪表盘值
    fn inc(&self);
    
    /// 增加仪表盘值（带有标签）
    fn inc_with_labels(&self, label_values: &[&str]);
    
    /// 减少仪表盘值
    fn dec(&self);
    
    /// 减少仪表盘值（带有标签）
    fn dec_with_labels(&self, label_values: &[&str]);
    
    /// 增加仪表盘值（指定数量）
    fn add(&self, value: f64);
    
    /// 增加仪表盘值（指定数量，带有标签）
    fn add_with_labels(&self, value: f64, label_values: &[&str]);
    
    /// 减少仪表盘值（指定数量）
    fn sub(&self, value: f64);
    
    /// 减少仪表盘值（指定数量，带有标签）
    fn sub_with_labels(&self, value: f64, label_values: &[&str]);
    
    /// 获取仪表盘当前值
    fn value(&self) -> f64;
    
    /// 获取带标签的仪表盘当前值
    fn value_with_labels(&self, label_values: &[&str]) -> f64;
}

/// 直方图接口
pub trait Histogram: Send + Sync + 'static {
    /// 记录值
    fn record(&self, value: f64);
    
    /// 记录值（带有标签）
    fn record_with_labels(&self, value: f64, label_values: &[&str]);
    
    /// 获取所有桶的计数
    fn buckets(&self) -> Vec<(f64, u64)>;
    
    /// 获取带标签的所有桶的计数
    fn buckets_with_labels(&self, label_values: &[&str]) -> Vec<(f64, u64)>;
    
    /// 获取总计数
    fn count(&self) -> u64;
    
    /// 获取带标签的总计数
    fn count_with_labels(&self, label_values: &[&str]) -> u64;
    
    /// 获取总和
    fn sum(&self) -> f64;
    
    /// 获取带标签的总和
    fn sum_with_labels(&self, label_values: &[&str]) -> f64;
}

/// 计时器辅助工具
pub struct Timer {
    /// 直方图引用
    histogram: Box<dyn Histogram>,
    /// 开始时间
    start: Instant,
    /// 标签值
    label_values: Vec<String>,
}

impl Timer {
    /// 创建新计时器
    pub fn new(histogram: Box<dyn Histogram>) -> Self {
        Self {
            histogram,
            start: Instant::now(),
            label_values: Vec::new(),
        }
    }
    
    /// 创建带标签的新计时器
    pub fn with_labels(histogram: Box<dyn Histogram>, label_values: &[&str]) -> Self {
        Self {
            histogram,
            start: Instant::now(),
            label_values: label_values.iter().map(|&s| s.to_string()).collect(),
        }
    }
    
    /// 观察经过的时间并记录到直方图
    pub fn observe(self) {
        let duration = Instant::now().duration_since(self.start);
        if self.label_values.is_empty() {
            self.histogram.record(duration.as_secs_f64());
        } else {
            let label_values: Vec<&str> = self.label_values.iter().map(|s| s.as_str()).collect();
            self.histogram.record_with_labels(duration.as_secs_f64(), &label_values);
        }
    }
}

/// 用于测试和开发的内存指标系统
pub struct MemoryMetrics {
    /// 计数器映射
    counters: HashMap<String, Arc<MemoryCounter>>,
    /// 仪表盘映射
    gauges: HashMap<String, Arc<MemoryGauge>>,
    /// 直方图映射
    histograms: HashMap<String, Arc<MemoryHistogram>>,
}

impl MemoryMetrics {
    /// 创建新的内存指标系统
    pub fn new() -> Self {
        Self {
            counters: HashMap::new(),
            gauges: HashMap::new(),
            histograms: HashMap::new(),
        }
    }
    
    /// 生成指标键
    fn generate_key(name: &str, labels: &[&str]) -> String {
        if labels.is_empty() {
            name.to_string()
        } else {
            format!("{}:{}", name, labels.join(","))
        }
    }
}

impl Default for MemoryMetrics {
    fn default() -> Self {
        Self::new()
    }
}

impl Metrics for MemoryMetrics {
    fn create_counter(&self, name: &str, description: &str, labels: &[&str]) -> Box<dyn Counter> {
        let key = Self::generate_key(name, labels);
        let counter = Arc::new(MemoryCounter::new(name, description, labels));
        
        // 不是线程安全的，但这只用于测试
        let mut counters = self.counters.clone();
        counters.insert(key, counter.clone());
        
        // 使用包装器返回
        Box::new(CounterWrapper(counter))
    }
    
    fn create_gauge(&self, name: &str, description: &str, labels: &[&str]) -> Box<dyn Gauge> {
        let key = Self::generate_key(name, labels);
        let gauge = Arc::new(MemoryGauge::new(name, description, labels));
        
        // 不是线程安全的，但这只用于测试
        let mut gauges = self.gauges.clone();
        gauges.insert(key, gauge.clone());
        
        // 使用包装器返回
        Box::new(GaugeWrapper(gauge))
    }
    
    fn create_histogram(&self, name: &str, description: &str, labels: &[&str], buckets: &[f64]) -> Box<dyn Histogram> {
        let key = Self::generate_key(name, labels);
        let histogram = Arc::new(MemoryHistogram::new(name, description, labels, buckets));
        
        // 不是线程安全的，但这只用于测试
        let mut histograms = self.histograms.clone();
        histograms.insert(key, histogram.clone());
        
        // 使用包装器返回
        Box::new(HistogramWrapper(histogram))
    }
}

/// 原子浮点数（Rust标准库中没有AtomicF64）
#[derive(Debug)]
pub struct AtomicF64 {
    inner: AtomicU64,
}

impl AtomicF64 {
    /// 创建新的原子浮点数
    pub fn new(value: f64) -> Self {
        Self {
            inner: AtomicU64::new(value.to_bits()),
        }
    }
    
    /// 加载值
    pub fn load(&self, order: Ordering) -> f64 {
        f64::from_bits(self.inner.load(order))
    }
    
    /// 存储值
    pub fn store(&self, value: f64, order: Ordering) {
        self.inner.store(value.to_bits(), order);
    }
    
    /// 获取并加
    pub fn fetch_add(&self, value: f64, order: Ordering) -> f64 {
        let mut current = self.load(order);
        let mut new;
        let mut bits;
        
        loop {
            new = current + value;
            bits = self.inner.compare_exchange(
                current.to_bits(),
                new.to_bits(),
                order,
                Ordering::Relaxed,
            );
            
            match bits {
                Ok(_) => return current,
                Err(b) => current = f64::from_bits(b),
            }
        }
    }
    
    /// 获取并减
    pub fn fetch_sub(&self, value: f64, order: Ordering) -> f64 {
        self.fetch_add(-value, order)
    }
}

/// 内存计数器实现
pub struct MemoryCounter {
    /// 名称
    name: String,
    /// 描述
    description: String,
    /// 标签名称列表
    labels: Vec<String>,
    /// 无标签值
    value: AtomicF64,
    /// 带标签值映射
    labeled_values: DashMap<String, AtomicF64>,
}

impl MemoryCounter {
    /// 创建新的内存计数器
    pub fn new(name: &str, description: &str, labels: &[&str]) -> Self {
        Self {
            name: name.to_string(),
            description: description.to_string(),
            labels: labels.iter().map(|&s| s.to_string()).collect(),
            value: AtomicF64::new(0.0),
            labeled_values: DashMap::new(),
        }
    }
    
    /// 生成标签键
    fn labels_key(&self, label_values: &[&str]) -> String {
        label_values.join(",")
    }
}

impl Counter for MemoryCounter {
    fn inc(&self) {
        self.add(1.0);
    }
    
    fn inc_with_labels(&self, label_values: &[&str]) {
        self.add_with_labels(1.0, label_values);
    }
    
    fn add(&self, value: f64) {
        self.value.fetch_add(value, Ordering::Relaxed);
    }
    
    fn add_with_labels(&self, value: f64, label_values: &[&str]) {
        let key = self.labels_key(label_values);
        self.labeled_values
            .entry(key)
            .or_insert_with(|| AtomicF64::new(0.0))
            .fetch_add(value, Ordering::Relaxed);
    }
    
    fn value(&self) -> f64 {
        self.value.load(Ordering::Relaxed)
    }
    
    fn value_with_labels(&self, label_values: &[&str]) -> f64 {
        let key = self.labels_key(label_values);
        match self.labeled_values.get(&key) {
            Some(v) => v.load(Ordering::Relaxed),
            None => 0.0,
        }
    }
}

/// 内存仪表盘实现
pub struct MemoryGauge {
    /// 名称
    name: String,
    /// 描述
    description: String,
    /// 标签名称列表
    labels: Vec<String>,
    /// 无标签值
    value: AtomicF64,
    /// 带标签值映射
    labeled_values: DashMap<String, AtomicF64>,
}

impl MemoryGauge {
    /// 创建新的内存仪表盘
    pub fn new(name: &str, description: &str, labels: &[&str]) -> Self {
        Self {
            name: name.to_string(),
            description: description.to_string(),
            labels: labels.iter().map(|&s| s.to_string()).collect(),
            value: AtomicF64::new(0.0),
            labeled_values: DashMap::new(),
        }
    }
    
    /// 生成标签键
    fn labels_key(&self, label_values: &[&str]) -> String {
        label_values.join(",")
    }
}

impl Gauge for MemoryGauge {
    fn set(&self, value: f64) {
        self.value.store(value, Ordering::Relaxed);
    }
    
    fn set_with_labels(&self, value: f64, label_values: &[&str]) {
        let key = self.labels_key(label_values);
        self.labeled_values
            .entry(key)
            .or_insert_with(|| AtomicF64::new(0.0))
            .store(value, Ordering::Relaxed);
    }
    
    fn inc(&self) {
        self.add(1.0);
    }
    
    fn inc_with_labels(&self, label_values: &[&str]) {
        self.add_with_labels(1.0, label_values);
    }
    
    fn dec(&self) {
        self.sub(1.0);
    }
    
    fn dec_with_labels(&self, label_values: &[&str]) {
        self.sub_with_labels(1.0, label_values);
    }
    
    fn add(&self, value: f64) {
        self.value.fetch_add(value, Ordering::Relaxed);
    }
    
    fn add_with_labels(&self, value: f64, label_values: &[&str]) {
        let key = self.labels_key(label_values);
        self.labeled_values
            .entry(key)
            .or_insert_with(|| AtomicF64::new(0.0))
            .fetch_add(value, Ordering::Relaxed);
    }
    
    fn sub(&self, value: f64) {
        self.value.fetch_sub(value, Ordering::Relaxed);
    }
    
    fn sub_with_labels(&self, value: f64, label_values: &[&str]) {
        let key = self.labels_key(label_values);
        self.labeled_values
            .entry(key)
            .or_insert_with(|| AtomicF64::new(0.0))
            .fetch_sub(value, Ordering::Relaxed);
    }
    
    fn value(&self) -> f64 {
        self.value.load(Ordering::Relaxed)
    }
    
    fn value_with_labels(&self, label_values: &[&str]) -> f64 {
        let key = self.labels_key(label_values);
        match self.labeled_values.get(&key) {
            Some(v) => v.load(Ordering::Relaxed),
            None => 0.0,
        }
    }
}

/// 内存直方图实现
pub struct MemoryHistogram {
    /// 名称
    name: String,
    /// 描述
    description: String,
    /// 标签名称列表
    labels: Vec<String>,
    /// 桶边界
    buckets: Vec<f64>,
    /// 无标签桶计数
    counts: Vec<AtomicU64>,
    /// 无标签总和
    sum: AtomicF64,
    /// 带标签桶计数和总和
    labeled_data: DashMap<String, (Vec<AtomicU64>, AtomicF64)>,
}

impl MemoryHistogram {
    /// 创建新的内存直方图
    pub fn new(name: &str, description: &str, labels: &[&str], buckets: &[f64]) -> Self {
        let counts = buckets.iter().map(|_| AtomicU64::new(0)).collect();
        
        Self {
            name: name.to_string(),
            description: description.to_string(),
            labels: labels.iter().map(|&s| s.to_string()).collect(),
            buckets: buckets.to_vec(),
            counts,
            sum: AtomicF64::new(0.0),
            labeled_data: DashMap::new(),
        }
    }
    
    /// 生成标签键
    fn labels_key(&self, label_values: &[&str]) -> String {
        label_values.join(",")
    }
    
    /// 获取或创建带标签的数据
    fn get_or_create_labeled_data(&self, label_values: &[&str]) -> dashmap::mapref::one::Ref<String, (Vec<AtomicU64>, AtomicF64)> {
        let key = self.labels_key(label_values);
        
        if !self.labeled_data.contains_key(&key) {
            let counts = self.buckets.iter().map(|_| AtomicU64::new(0)).collect();
            let sum = AtomicF64::new(0.0);
            self.labeled_data.insert(key.clone(), (counts, sum));
        }
        
        self.labeled_data.get(&key).unwrap()
    }
}

impl Histogram for MemoryHistogram {
    fn record(&self, value: f64) {
        // 更新总和
        self.sum.fetch_add(value, Ordering::Relaxed);
        
        // 更新桶计数
        for (i, &bucket) in self.buckets.iter().enumerate() {
            if value <= bucket {
                self.counts[i].fetch_add(1, Ordering::Relaxed);
            }
        }
    }
    
    fn record_with_labels(&self, value: f64, label_values: &[&str]) {
        let data = self.get_or_create_labeled_data(label_values);
        let (counts, sum) = &*data;
        
        // 更新总和
        sum.fetch_add(value, Ordering::Relaxed);
        
        // 更新桶计数
        for (i, &bucket) in self.buckets.iter().enumerate() {
            if value <= bucket {
                counts[i].fetch_add(1, Ordering::Relaxed);
            }
        }
    }
    
    fn buckets(&self) -> Vec<(f64, u64)> {
        self.buckets
            .iter()
            .zip(self.counts.iter())
            .map(|(&bucket, count)| (bucket, count.load(Ordering::Relaxed)))
            .collect()
    }
    
    fn buckets_with_labels(&self, label_values: &[&str]) -> Vec<(f64, u64)> {
        if let Some(data) = self.labeled_data.get(&self.labels_key(label_values)) {
            let (counts, _) = &*data;
            self.buckets
                .iter()
                .zip(counts.iter())
                .map(|(&bucket, count)| (bucket, count.load(Ordering::Relaxed)))
                .collect()
        } else {
            self.buckets.iter().map(|&bucket| (bucket, 0)).collect()
        }
    }
    
    fn count(&self) -> u64 {
        let mut total = 0;
        for count in &self.counts {
            total = total.max(count.load(Ordering::Relaxed));
        }
        total
    }
    
    fn count_with_labels(&self, label_values: &[&str]) -> u64 {
        if let Some(data) = self.labeled_data.get(&self.labels_key(label_values)) {
            let (counts, _) = &*data;
            let mut total = 0;
            for count in counts {
                total = total.max(count.load(Ordering::Relaxed));
            }
            total
        } else {
            0
        }
    }
    
    fn sum(&self) -> f64 {
        self.sum.load(Ordering::Relaxed)
    }
    
    fn sum_with_labels(&self, label_values: &[&str]) -> f64 {
        if let Some(data) = self.labeled_data.get(&self.labels_key(label_values)) {
            let (_, sum) = &*data;
            sum.load(Ordering::Relaxed)
        } else {
            0.0
        }
    }
}

// Counter包装器，解决Box<Arc<T>>问题
struct CounterWrapper(Arc<MemoryCounter>);

impl Counter for CounterWrapper {
    fn inc(&self) {
        self.0.inc();
    }
    
    fn inc_with_labels(&self, label_values: &[&str]) {
        self.0.inc_with_labels(label_values);
    }
    
    fn add(&self, value: f64) {
        self.0.add(value);
    }
    
    fn add_with_labels(&self, value: f64, label_values: &[&str]) {
        self.0.add_with_labels(value, label_values);
    }
    
    fn value(&self) -> f64 {
        self.0.value()
    }
    
    fn value_with_labels(&self, label_values: &[&str]) -> f64 {
        self.0.value_with_labels(label_values)
    }
}

// Gauge包装器，解决Box<Arc<T>>问题
struct GaugeWrapper(Arc<MemoryGauge>);

impl Gauge for GaugeWrapper {
    fn set(&self, value: f64) {
        self.0.set(value);
    }
    
    fn set_with_labels(&self, value: f64, label_values: &[&str]) {
        self.0.set_with_labels(value, label_values);
    }
    
    fn inc(&self) {
        self.0.inc();
    }
    
    fn inc_with_labels(&self, label_values: &[&str]) {
        self.0.inc_with_labels(label_values);
    }
    
    fn dec(&self) {
        self.0.dec();
    }
    
    fn dec_with_labels(&self, label_values: &[&str]) {
        self.0.dec_with_labels(label_values);
    }
    
    fn add(&self, value: f64) {
        self.0.add(value);
    }
    
    fn add_with_labels(&self, value: f64, label_values: &[&str]) {
        self.0.add_with_labels(value, label_values);
    }
    
    fn sub(&self, value: f64) {
        self.0.sub(value);
    }
    
    fn sub_with_labels(&self, value: f64, label_values: &[&str]) {
        self.0.sub_with_labels(value, label_values);
    }
    
    fn value(&self) -> f64 {
        self.0.value()
    }
    
    fn value_with_labels(&self, label_values: &[&str]) -> f64 {
        self.0.value_with_labels(label_values)
    }
}

// Histogram包装器，解决Box<Arc<T>>问题
struct HistogramWrapper(Arc<MemoryHistogram>);

impl Histogram for HistogramWrapper {
    fn record(&self, value: f64) {
        self.0.record(value);
    }
    
    fn record_with_labels(&self, value: f64, label_values: &[&str]) {
        self.0.record_with_labels(value, label_values);
    }
    
    fn buckets(&self) -> Vec<(f64, u64)> {
        self.0.buckets()
    }
    
    fn buckets_with_labels(&self, label_values: &[&str]) -> Vec<(f64, u64)> {
        self.0.buckets_with_labels(label_values)
    }
    
    fn count(&self) -> u64 {
        self.0.count()
    }
    
    fn count_with_labels(&self, label_values: &[&str]) -> u64 {
        self.0.count_with_labels(label_values)
    }
    
    fn sum(&self) -> f64 {
        self.0.sum()
    }
    
    fn sum_with_labels(&self, label_values: &[&str]) -> f64 {
        self.0.sum_with_labels(label_values)
    }
} 